﻿#include "Sprite.h"

Sprite::Sprite(const std::string& stateID, Animation anim)
{
    animations[stateID] = std::move(anim);
    currentState = stateID;
}

Sprite::Sprite(const std::string& stateID,
    LPCTSTR framePathFormat,
    int frameCount,
    int interval,
    bool isLoop)
{
    auto atlas = std::make_shared<TextureAtlasAsset>(stateID, framePathFormat, frameCount);
    atlas->Load();

    Animation anim;
    anim.set_atlas(atlas);
    anim.set_interval(interval);
    anim.set_loop(isLoop);
    animations[stateID] = std::move(anim);
    currentState = stateID;

}


bool Sprite::AddState(const std::string& stateID,
    LPCTSTR framePathFormat,
    int frameCount,
    int interval,
    bool isLoop) {
    auto Atlas = std::make_shared<TextureAtlasAsset>(stateID, framePathFormat, frameCount);
    Atlas->Load();

    // 设置正向动画
    Animation anim;
    anim.set_atlas(Atlas);
    anim.set_interval(interval);
    anim.set_loop(isLoop);
    animations[stateID] = std::move(anim);

    /*
    // 创建翻转图集
    TextureAtlasAsset* AtlastFlipped = Atlas->CreateFlipped(stateID + "_flip");
    Animation animFlip;
    animFlip.set_atlas(AtlastFlipped);
    animFlip.set_interval(interval);
    animFlip.set_loop(isLoop);
    animations[stateID + "_flip"] = std::move(animFlip);
    */
    return true;
}


bool Sprite::SetState(const StateID& id, const Vector2& startPos) {
    if (animations.find(id) == animations.end()) return false;
    currentState = id;
    position = startPos;
    return true;
}


bool Sprite::AddFlipAnim(const StateID& id, const StateID& id_flip)
{
    auto it = animations.find(id);
    if (it == animations.end()) return false;
    Animation anim = animations[id];
    std::shared_ptr<TextureAtlasAsset> Atlas = anim.GetAtlas();
    std::shared_ptr<TextureAtlasAsset> AtlastFlipped = Atlas->CreateFlipped(id_flip);
    Animation animFlip;
    animFlip.set_atlas(AtlastFlipped);
    animFlip.set_interval(anim.GetInterval());
    animFlip.set_loop(anim.GetIsloop());
    animations[id_flip] = std::move(animFlip);
    return true;
}
void Sprite::SetTransition(const StateID& fromID, const StateID& toID)
{

    transitions[fromID] = toID;
    // 对翻转状态同样操作
    StateID f = fromID + "_flip", t = toID + "_flip";
    transitions[f] = t;
}

void Sprite::SetCallback(const StateID& id, Callback callback)
{
    auto it = animations.find(id);
    if (it != animations.end())
    {
        it->second.set_callback(callback);
    }
}

void Sprite::ChangeState(const StateID& id)
{
    if (!caninterupt) return;
    if (currentState == id || animations.find(id) == animations.end()) return;
    currentState = id;
    animations[id].reset();
}

void Sprite::Update(int delta)
{
    if (!caninterupt)
    {
        auto it = animations.find(captureState);
        if (it != animations.end())
        {
            currentState = captureState;
        }

    }

    animations[currentState].on_update(delta);
    if (!animations[currentState].GetIsloop() && animations[currentState].check_finished()) {
        caninterupt = true;
        Callback fun = animations[currentState].GetCallback();
        if (fun) fun();
        StateID id = transitions[currentState];
        auto it = animations.find(id);
        if (it != animations.end())
        {
            currentState = id;
            animations[id].reset();
        }
    }

    if (is_playing_timed_anim)
    {
        DWORD check_time = GetTickCount();

        if (check_time - AnimStartTime > AnimDuration)
        {
            is_playing_timed_anim = false;
            AnimStartTime = 0;
            AnimDuration = 0;
            caninterupt = true;
        }
    }
}

void Sprite::Draw(const Camera& cam) const
{
    Animation anim = animations.at(currentState);
    anim.on_draw(cam, int(position.x), int(position.y));
}
void Sprite::Play(const StateID& id, bool loop) {
    caninterupt = false;
    captureState = id;
    auto it = animations.find(id);
    if (it == animations.end()) return;
    // 切状态并重置
    currentState = id;
    Animation& anim = it->second;
    anim.reset();
    anim.set_loop(loop);
    // 先清掉之前的回调标志
    //anim.set_callback(nullptr);
    //std::cout << transitions[id] << std::endl;
    // 绑定新的回调
    //anim.set_callback([this,id,toID]() {
    //        ChangeState(toID);
    //        });
}

void Sprite::Play(const StateID& id, DWORD duration, bool if_interruptible)
{
    //检查id是否存在
    auto it = animations.find(id);
    if (it == animations.end()) return;

    AnimStartTime = GetTickCount();
    AnimDuration = duration;
    caninterupt = if_interruptible;
    is_playing_timed_anim = true;
    captureState = id;
    currentState = id;
    Animation& anim = it->second;
    anim.reset();
}

void Sprite::SwitchFacingDuringPlay(bool left) {
    // 推导 flip 状态名
    std::string baseState = currentState;
    bool isFlipped = false;

    if (baseState.size() > 5 && baseState.substr(baseState.size() - 5) == "_flip") {
        baseState = baseState.substr(0, baseState.size() - 5);
        isFlipped = true;
    }

    if (left && !isFlipped && animations.count(baseState + "_flip")) {
        // 切换到 flip 版本，不重置帧
        Animation& currentAnim = animations[currentState];
        int currentFrame = currentAnim.get_idx_frame();
        currentState = baseState + "_flip";
        animations[currentState].set_idx_frame(currentFrame);
    }
    else if (!left && isFlipped && animations.count(baseState)) {
        // 切换回非翻转版本
        Animation& currentAnim = animations[currentState];
        int currentFrame = currentAnim.get_idx_frame();
        currentState = baseState;
        animations[currentState].set_idx_frame(currentFrame);
    }
}

bool Sprite::SwitchSimultaneously(const StateID& target_id)
{
    auto it = animations.find(target_id);
    if (it == animations.end()) return false;
    Animation current_anim = animations[currentState];
    int current_frame = current_anim.get_idx_frame();
    currentState = target_id;
    //Animation next_anim = animations[target_id];
    //if (current_frame < next_anim.GetFrameCount()) return false;
    animations[currentState].set_idx_frame(current_frame);
    //next_anim.set_idx_frame(current_frame);
    return true;
}
void Sprite::Move(float dx, float dy) {
    position.x += dx;
    position.y += dy;
}

void Sprite::SetPos(float x, float y) {
    position.x = x;
    position.y = y;
}